/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.stuffrepos.bricknetcenter.http;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import net.stuffrepos.bricknetcenter.http.HttpRequest.PostParameter;
import net.stuffrepos.bricknetcenter.http.util.HttpParserHelper;
import net.stuffrepos.bricknetcenter.util.Debug;
import net.stuffrepos.bricknetcenter.util.TimeMarker;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.NameValuePair;
import org.apache.http.StatusLine;
import org.apache.http.client.HttpClient;
import org.apache.http.client.HttpResponseException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;

/**
 *
 * @author Eduardo H. Bogoni <eduardobogoni@gmail.com>
 */
public class HttpDownloader {

    private static final Log log = LogFactory.getLog(HttpDownloader.class);
    private HttpClient httpClient = new DefaultHttpClient();

    public void download(HttpRequest source) throws Exception {

        try {
            TimeMarker marker = new TimeMarker();
            marker.mark("Start");
            HttpResponse response = new WebPageResponseImpl(source);
            marker.mark("Requesting");
            HttpParserHelper.createParser(source).parse(response);
            marker.mark("Parsing");
            if (log.isDebugEnabled()) {
                log.debug("Results for \"" + source.getUrl() + "\":\n" + marker.toString());
            }
        } catch (Exception ex) {
            log.warn("Exception on processing request " + Debug.requestToString(source), ex);
            httpClient.getConnectionManager().shutdown();
            httpClient = new DefaultHttpClient();
        }
    }

    public void stopExecutionImmediately() {
        httpClient.getConnectionManager().shutdown();        
    }

    private class WebPageResponseImpl implements HttpResponse {

        private final HttpRequest request;
        private final org.apache.http.HttpResponse response;

        private WebPageResponseImpl(HttpRequest source) throws IOException {
            this.request = source;

            HttpRequestBase requestBase;

            switch (source.getMethod()) {
                case Post:
                    HttpPost post = new HttpPost(source.getUrl().toExternalForm());
                    List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>(1);
                    for (PostParameter postParameter : source.getPostParameters()) {
                        nameValuePairs.add(new BasicNameValuePair(
                                postParameter.getName(),
                            postParameter.getValue()));
                    }
                    
                    
                    post.setEntity(new UrlEncodedFormEntity(nameValuePairs));

                    requestBase = post;
                    break;

                case Get:
                default:
                    requestBase = new HttpGet(source.getUrl().toExternalForm());
                    break;
            }

            if (source.getReferer() != null) {
                requestBase.setHeader("referer", source.getReferer().toExternalForm());
            }

            requestBase.setHeader("Host", source.getUrl().getHost());
            requestBase.setHeader("User-Agent", "Mozilla/5.0 (X11; U; Linux x86_64; pt-BR; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.04 (lucid) Firefox/3.6.13");
            requestBase.setHeader("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
            requestBase.setHeader("Accept-Language", "pt-br,pt;q=0.8,en-us;q=0.5,en;q=0.3");
            requestBase.setHeader("Accept-Encoding", "gzip,deflate");
            requestBase.setHeader("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.7");
            requestBase.setHeader("Keep-Alive", "115");
            requestBase.setHeader("Connection", "keep-alive");

            log.trace("Downloading " + requestBase.getURI() + "...");
            response = httpClient.execute(requestBase);
            //response.get

            StatusLine statusLine = response.getStatusLine();
            if (statusLine.getStatusCode() >= 300) {
                throw new HttpResponseException(statusLine.getStatusCode(),
                        statusLine.getReasonPhrase());
            }
        }

        @Override
        public InputStream getInputStream() {
            try {
                return response.getEntity().getContent();
            } catch (IOException ex) {
                throw new RuntimeException(ex);
            } catch (IllegalStateException ex) {
                throw new RuntimeException(ex);
            }
        }

        @Override
        public URL getUrl() {
            return request.getUrl();
        }

        @Override
        public String getContentEncoding() {
            if (response.getEntity() != null && response.getEntity().getContentEncoding() != null) {
                return response.getEntity().getContentEncoding().getValue();
            } else {
                return null;
            }

        }

        @Override
        public String getMimeType() {
            return response.getFirstHeader("Content-type").getValue();
        }
    }
}
